package com.gamecollection.snake.model;

import com.gamecollection.mvc.Model;
import com.gamecollection.snake.model.obj.BodyObj;
import com.gamecollection.snake.model.obj.FoodObj;
import com.gamecollection.snake.model.obj.HeadObj;
import com.gamecollection.snake.utils.GameUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 贪吃蛇游戏模型
 */
public class SnakeModel implements Model {
    
    // 游戏状态常量
    public static final int STATE_NOT_STARTED = 0;
    public static final int STATE_PLAYING = 1;
    public static final int STATE_PAUSED = 2;
    public static final int STATE_GAME_OVER = 3;
    public static final int STATE_LEVEL_COMPLETE = 4;
    public static final int STATE_RESTART = 5;
    public static final int STATE_NEXT_LEVEL = 6;
    
    private int gameState = STATE_NOT_STARTED;
    private int score = 0;
    private int level = 1;
    
    // 移动速度控制
    private int moveCounter = 0;
    private int moveInterval = 8; // 每8帧移动一次，原来是每帧都移动
    
    // 蛇头对象
    private HeadObj headObj;
    
    // 蛇身体集合
    private List<BodyObj> bodyObjList;
    
    // 食物对象
    private FoodObj foodObj;
    
    // 游戏区域尺寸
    private int gameWidth = 600;
    private int gameHeight = 600;
    
    public SnakeModel() {
        bodyObjList = new ArrayList<>();
    }
    
    @Override
    public void initialize() {
        // 初始化蛇头
        headObj = new HeadObj(GameUtils.rightImg, 60, 570, this);
        
        // 初始化蛇身体
        bodyObjList.clear();
        bodyObjList.add(new BodyObj(GameUtils.bodyImg, 30, 570, this));
        bodyObjList.add(new BodyObj(GameUtils.bodyImg, 0, 570, this));
        
        // 初始化食物
        foodObj = new FoodObj().getFood();
        
        // 重置游戏状态
        gameState = STATE_NOT_STARTED;
        score = 0;
        level = 1;
        moveCounter = 0;
        
        // 根据关卡调整速度
        updateSpeed();
    }
    
    @Override
    public void update() {
        if (gameState == STATE_PLAYING) {
            moveCounter++;
            
            // 每moveInterval帧移动一次
            if (moveCounter >= moveInterval) {
                moveCounter = 0;
                
                // 更新蛇头位置
                headObj.update();
                
                // 更新蛇身体位置
                for (BodyObj body : bodyObjList) {
                    body.update();
                }
                
                // 检查碰撞
                checkCollisions();
                
                // 检查是否吃到食物
                checkFoodCollision();
            }
        }
    }
    
    @Override
    public void reset() {
        initialize();
    }
    
    @Override
    public int getGameState() {
        return gameState;
    }
    
    @Override
    public void setGameState(int state) {
        this.gameState = state;
    }
    
    /**
     * 根据关卡更新速度
     */
    private void updateSpeed() {
        switch (level) {
            case 1:
                moveInterval = 8; // 最慢
                break;
            case 2:
                moveInterval = 6; // 中等
                break;
            case 3:
                moveInterval = 4; // 较快
                break;
        }
    }
    
    /**
     * 检查碰撞
     */
    private void checkCollisions() {
        // 检查蛇头是否撞墙
        if (headObj.getX() < 0 || headObj.getX() >= gameWidth || 
            headObj.getY() < 0 || headObj.getY() >= gameHeight) {
            gameState = STATE_GAME_OVER;
            return;
        }
        
        // 检查蛇头是否撞到身体
        for (BodyObj body : bodyObjList) {
            if (headObj.getX() == body.getX() && headObj.getY() == body.getY()) {
                gameState = STATE_GAME_OVER;
                return;
            }
        }
    }
    
    /**
     * 检查是否吃到食物
     */
    private void checkFoodCollision() {
        if (headObj.getX() == foodObj.getX() && headObj.getY() == foodObj.getY()) {
            // 增加分数
            score += 10;
            
            // 增加蛇身体
            BodyObj lastBody = bodyObjList.get(bodyObjList.size() - 1);
            BodyObj newBody = new BodyObj(GameUtils.bodyImg, 
                lastBody.getX(), lastBody.getY(), this);
            bodyObjList.add(newBody);
            
            // 生成新食物
            foodObj = new FoodObj().getFood();
            
            // 检查是否达到过关条件
            if (score >= level * 50) {
                if (level >= 3) {
                    gameState = STATE_LEVEL_COMPLETE;
                } else {
                    gameState = STATE_NEXT_LEVEL;
                }
            }
        }
    }
    
    /**
     * 增加分数
     */
    public void addScore(int points) {
        score += points;
    }
    
    /**
     * 下一关
     */
    public void nextLevel() {
        level++;
        score = 0;
        updateSpeed(); // 更新速度
        initialize();
    }
    
    // Getter方法
    public HeadObj getHeadObj() {
        return headObj;
    }
    
    public List<BodyObj> getBodyObjList() {
        return bodyObjList;
    }
    
    public FoodObj getFoodObj() {
        return foodObj;
    }
    
    public int getScore() {
        return score;
    }
    
    public int getLevel() {
        return level;
    }
    
    public int getGameWidth() {
        return gameWidth;
    }
    
    public int getGameHeight() {
        return gameHeight;
    }
} 